package com.xcesys.extras.dataobject;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class QueryObject implements Serializable {

	private static final int DEFAULT_PAGE_SIZE = 20;

	private static final long serialVersionUID = -3889163980071720827L;

	public static final String DIRECTION_ASC = "asc";

	public static final String DIRECTION_DESC = "desc";

	/**
	 * Order direction.
	 */
	private String direction = DIRECTION_ASC;

	/**
	 * Current page.
	 */
	private int page = 1;

	/**
	 * Query condition by specific business object in a pair of Key and Value.
	 */
	private Map<String, Object> map = new HashMap<String, Object>();

	/**
	 * max query result line per page, default is 20.
	 */
	private int pageSize = DEFAULT_PAGE_SIZE;

	/**
	 * Order field, null if order not required.
	 */
	private String sort = null;

	/**
	 * The start index of results to get, starts with 0.
	 */
	private int startIndex = 0;

	/**
	 * Total record count.
	 */
	private int totalCount;

	/**
	 * Total page count.
	 */
	private int totalPage;

	public QueryObject() {
	}

	public QueryObject(int pageSize) {
		this.pageSize = pageSize;
	}

	public boolean containsKey(Object key) {
		if (map.containsKey(key)) {
			if (map.get(key) instanceof String) {
				if (!isNullOrBlank(map.get(key))) {
					return true;
				}
			} else {
				return true;
			}
		}

		return false;
	}

	/**
	 * @return the orderDirection
	 */
	public String getDirection() {
		return direction;
	}

	public Map<String, Object> getMap() {
		return map;
	}

	public int getPage() {
		return page;
	}

	/**
	 * @return the pageSize
	 */
	public int getPageSize() {
		return pageSize;
	}

	/**
	 * @return the orderField
	 */
	public String getSort() {
		return sort;
	}

	public int getStartIndex() {
		return startIndex;
	}

	public int getTotalCount() {
		return totalCount;
	}

	public int getTotalPage() {
		return totalPage;
	}

	public boolean isEmpty() {
		if (map.isEmpty()) {
			return true;
		}
		for (Object key : map.keySet()) {
			Object v = map.get(key);
			if (v != null) {
				if (v instanceof String && isNullOrBlank(v)) {
					return false;
				}
			}
		}
		return true;
	}

	private boolean isNullOrBlank(Object v) {
		return v == null || "".equals(v);
	}

	public void put(String key, Object value) {
		map.put(key, value);
	}

	public void reset() {
		startIndex = 0;
		sort = null;
		page = 1;
		pageSize = DEFAULT_PAGE_SIZE;
		direction = DIRECTION_ASC;
		totalCount = 0;
		totalPage = 0;
		map.clear();
	}

	/**
	 * @param direction
	 *            the orderDirection to set
	 */
	public void setDirection(String direction) {
		if (!DIRECTION_ASC.equalsIgnoreCase(direction)
				&& !DIRECTION_DESC.equalsIgnoreCase(direction)) {
			this.direction = DIRECTION_ASC;
		} else {
			this.direction = direction;
		}
	}

	/**
	 * Set current page, the value will cause startIndex be recaculated.
	 * 
	 * @param page
	 *            current page number.
	 * @see {@link #setStartIndex(int)}
	 */
	public void setPage(int page) {
		this.page = (page < 1 ? 1 : page);
		this.startIndex = this.page > 1 ? (this.page - 1) * getPageSize() : 0;
	}

	/**
	 * @param pageSize
	 *            the pageSize to set
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * @param orderField
	 *            the orderField to set
	 */
	public void setSort(String orderField) {
		this.sort = orderField;
	}

	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
}
